﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DataTier.Repository;
using System.ServiceModel;
using DataTier.Entities;
using DataTier;
using Common;

namespace Otgruzka.ServicesClients
{
    public class ExpendBillsClient
    {

        public readonly ExpendBillRepository Repository = null;

        public ExpendBillsClient()
        {
            this.Repository = new ExpendBillRepository();
        }


        /// <summary>
        /// Возвращает полный текст Exceptions вместе с вложенными Exceptions
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public string GetExceptionDetail(System.ServiceModel.FaultException<ExceptionDetail> ex)
        {
            string message = ex.Message;

            var ie = ex.InnerException;
            while (ie != null)
            {
                message += string.Format("<br />{0}", ie.Message);
                ie = ie.InnerException;
            }

            var ed = ex.Detail;
            do
            {
                message += string.Format("<br />{0}", ed.Message);
                ed = ed.InnerException;
            } while (ed != null);
            return message;
        }


        /// <summary>
        /// Возвращает список всех Расходных накладных по всем из базы данных
        /// </summary>
        /// <returns></returns>
        public List<ExpendBillEntity> GetExpendBillAllList(int currentUserId, int numPage, int onPage, SearchParameters parameters = null)
        {
            try
            {
                var bills = Repository.GetExpendBillAllList(currentUserId, numPage, onPage, parameters);
                return bills;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить список Расходных накладных из базы данных.");
            }
        }


        /// <summary>
        /// Возвращает количество Расходных накладных по всем заказам из базы данных
        /// </summary>
        /// <returns></returns>
        public int GetExpendBillAllListCount(int currentUserId, SearchParameters parameters = null)
        {
            try
            {
                return Repository.GetExpendBillAllListCount(currentUserId, parameters);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                return 0;
            }
        }


        /// <summary>
        /// Возвращает список всех Расходных накладных по конкретногму Заказу из базы данных
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public List<ExpendBillEntity> GetExpendBillList(int currentUserId, bool onlyIts, int orderId)
        {
            try
            {
                var bills = Repository.GetExpendBillList(currentUserId, onlyIts, orderId);
                return bills;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить список Расходных накладных из базы данных.");
            }
        }


        /// <summary>
        /// Возвращает Расходную накладную из базы данных
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public ExpendBillEntity GetExpendBill(int currentUserId, int id)
        {
            try
            {
                var bill = this.Repository.GetExpendBill(currentUserId, id);
                return bill;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить Расходную накладную из базы данных.");
            }
        }


        /// <summary>
        /// Формируется новый объект Расходная накладная по конкретному Заказу
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public ExpendBillEntity CreateNewExpendBill(int currentUserId, int orderId)
        {
            try
            {
                var bill = Repository.CreateNewExpendBill(currentUserId, orderId);
                return bill;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сформировать новую Расходную накладную.");
            }
        }


        /// <summary>
        /// Сохранение Расходной накладной в базе данных
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="newExpendBill"></param>
        /// <returns></returns>
        public int SaveExpendBill(int currentUserId, ExpendBillEntity newExpendBill)
        {
            try
            {
                var expendBillId = Repository.SaveExpendBill(currentUserId, newExpendBill);
                return expendBillId;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сохранить Расходную накладную в базу данных.");
            }
        }


        /// <summary>
        /// Удаляются записи из Накладной
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="newExpendBillId"></param>
        /// <param name="productIDs"></param>
        public void RemoveProductsFromExpendBill(int currentUserId, int newExpendBillId, int[] productIDs)
        {
            try
            {
                Repository.RemoveProductsFromExpendBill(currentUserId, newExpendBillId, productIDs);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке удалить из базы данных строки с товарами в Расходной накладной.");
            }
        }


        /// <summary>
        /// Обновление количества товаров в указанных Накладных 
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="billsForModif"></param>
        public void UpdateProductsFromExpendBills(int currentUserId, BillProductCountComposite[] billsForModif)
        {
            try
            {
                Repository.UpdateProductsFromExpendBills(currentUserId, billsForModif.ToList());
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке обновить в базе данных строки с товарами в Расходных накладных.");
            }
        }


        /// <summary>
        /// Удаление Расходной накладной
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="expendBillId"></param>
        public void DeleteExpendBill(int currentUserId, int expendBillId)
        {
            try
            {
                Repository.DeleteExpendBill(currentUserId, expendBillId);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке удалить Расходную накладную из базы данных.");
            }
        }


        /// <summary>
        /// Обновление товаров в спецификации Накладной и связанного с ней Заказа
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="orderId"></param>
        public void RefreshExpendBillSpecAndOrderSpec(int currentUserId, int expendBillId)
        {
            try
            {
                Repository.RefreshExpendBillSpecAndOrderSpec(currentUserId, expendBillId);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке обновить список товаров в Расходной накладной и в Заказе в базе данных.");
            }
        }



        /// <summary>
        /// Формирует новый консолидированный счет
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="costCenterId"></param>
        /// <param name="dateBegin"></param>
        /// <param name="dateEnd"></param>
        /// <returns></returns>
        public ConsolidatedAccountEntity CreateConsolidatedAccount(int currentUserId, int juridicalPersonId, DateTime dateBegin, DateTime dateEnd)
        {
            try
            {
                var account = Repository.CreateConsolidatedAccount(currentUserId, juridicalPersonId, dateBegin, dateEnd);
                return account;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сформировать Консолидированный счет.");
            }
        }

         
        /// <summary>
        /// Возвращает объект Консолидированный Счет
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="accountId"></param>
        /// <returns></returns>
        public ConsolidatedAccountEntity GetConsolidatedAccount(int currentUserId, int accountId)
        {
            try
            {
                var account = Repository.GetConsolidatedAccount(currentUserId, accountId);
                return account;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке найти Консолидированный счет в базе данных.");
            }
        }

         
        /// <summary>
        /// Сохранение Консолидированного счета в базе данных
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="newConsolidatedAccount"></param>
        /// <returns></returns>
        public int SaveConsolidatedAccount(int currentUserId, ConsolidatedAccountEntity newConsolidatedAccount)
        {
            try
            {
                int accountId = Repository.SaveConsolidatedAccount(currentUserId, newConsolidatedAccount);
                return accountId;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сохранить Консолидированный счет в базу данных.");
            }
        }


        /// <summary>
        /// Возвращает список Консолидированных счетов из базы данных
        /// </summary>
        /// <returns></returns>
        public List<ConsolidatedAccountEntity> GetConsolidatedAccountList(int currentUserId, int numPage, int onPage, SearchParameters parameters)
        {
            try
            {
                var accounts = Repository.GetConsolidatedAccountList(currentUserId, numPage, onPage, parameters);
                return accounts;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить список Консолидированных счетов из базы данных.");
            }
        }


        /// <summary>
        /// Возвращает количество Консолидированных счетов из базы данных
        /// </summary>
        /// <returns></returns>
        public int GetConsolidatedAccountListCount(int currentUserId, SearchParameters parameters)
        {
            try
            {
                return Repository.GetConsolidatedAccountListCount(currentUserId, parameters);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                return 0;
            }
        }



        /// <summary>
        /// Формирует новый консолидированный счет
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="costCenterId"></param>
        /// <param name="dateBegin"></param>
        /// <param name="dateEnd"></param>
        /// <returns></returns>
        public CAEntity2 CreateConsolidatedAccount2(int currentUserId, int juridicalPersonId, DateTime dateBegin, DateTime dateEnd)
        {
            try
            {
                var account = Repository.CreateConsolidatedAccount2(currentUserId, juridicalPersonId, dateBegin, dateEnd);
                return account;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сформировать Консолидированный счет.");
            }
        }


        /// <summary>
        /// Возвращает объект Консолидированный Счет
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="accountId"></param>
        /// <returns></returns>
        public CAEntity2 GetConsolidatedAccount2(int currentUserId, int accountId)
        {
            try
            {
                var account = Repository.GetConsolidatedAccount2(currentUserId, accountId);
                return account;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке найти Консолидированный счет в базе данных.");
            }
        }


        /// <summary>
        /// Сохранение Консолидированного счета в базе данных
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="newConsolidatedAccount"></param>
        /// <returns></returns>
        public int SaveConsolidatedAccount2(int currentUserId, CAEntity2 newConsolidatedAccount)
        {
            try
            {
                int accountId = Repository.SaveConsolidatedAccount2(currentUserId, newConsolidatedAccount);
                return accountId;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке сохранить Консолидированный счет в базу данных.");
            }
        }


        /// <summary>
        /// Возвращает список Консолидированных счетов из базы данных
        /// </summary>
        /// <returns></returns>
        public List<CAEntity2> GetConsolidatedAccountList2(int currentUserId, int numPage, int onPage, SearchParameters parameters)
        {
            try
            {
                var accounts = Repository.GetConsolidatedAccountList2(currentUserId, numPage, onPage, parameters);
                return accounts;
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить список Консолидированных счетов из базы данных.");
            }
        }


        /// <summary>
        /// Возвращает количество Консолидированных счетов из базы данных
        /// </summary>
        /// <returns></returns>
        public int GetConsolidatedAccountListCount2(int currentUserId, SearchParameters parameters)
        {
            try
            {
                return Repository.GetConsolidatedAccountListCount2(currentUserId, parameters);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                return 0;
            }
        }



        /// <summary>
        /// Возвращает объединенный объект для экспортной формы Отгрузка (на основании Консолидированного счета)
        /// </summary>
        /// <param name="accountId"></param>
        /// <returns></returns>
        public ConsolidatedAccountOtgruzkaEntity GetConsolidatedAccountOtgruzka(int accountId)
        {
            try
            {
                return Repository.GetConsolidatedAccountOtgruzka(accountId);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить объект для экспортной формы \"Отгрузка\".");
            }
        }


        /// <summary>
        /// Возвращает объединенный объект для экспортной формы Накладная (на основании Консолидированного счета)
        /// </summary>
        /// <param name="accountId"></param>
        /// <returns></returns>
        public ConsolidatedAccountInvoiceEntity GetConsolidatedAccountInvoice(int accountId)
        {
            try
            {
                return Repository.GetConsolidatedAccountInvoice(accountId);
            }
            catch (Exception ex)
            {
                new Logger().LogException(ex);
                throw new FaultException<ExceptionDetail>(new ExceptionDetail(ex), "Произошла ошибка при попытке получить объект для экспортной формы \"Накладная\".");
            }
        }

    }
}